package edu.chalmers.targine;

import java.util.ArrayList;

import org.cocos2d.layers.CCColorLayer;
import org.cocos2d.layers.CCLayer;
import org.cocos2d.layers.CCScene;
import org.cocos2d.nodes.CCDirector;
import org.cocos2d.types.CGPoint;
import org.cocos2d.types.CGRect;
import org.cocos2d.types.ccColor4B;

import android.view.MotionEvent;

/** Game layer handles UI, content and game loop */
public class GameLayer extends CCColorLayer{
	public static GameLayer scene;
	private ArrayList<CocosComponent> cocosComponents = new ArrayList<CocosComponent>();
	private ARManager arManager;
	
	// Fields
//	private NFCFeedback _nfcFeedback;
//	private ActionSlots _actions;
//	public static GameLayer scene;
//	private ARManager arManager;
//
//	private Arbject currentArbject;
//	
//	public static int RAY_ITERATIONS = 1000;
//	public static float COLLISION_RADIUS = 0.1f;
//	
//	float count = 0f;
	
	/**Constructor sets up game components*/
	protected GameLayer(ccColor4B color){
		super(color);
	    //Schedule update and enable touch
	    this.schedule("update");
	    this.setIsTouchEnabled(true);
	    this.setIsAccelerometerEnabled(true);
	    
//	    super(color);
//	    CGSize winSize = CCDirector.sharedDirector().displaySize();
//	    //Add d-pad graphics
//	    _nfcFeedback = new NFCFeedback("d-pad.png", 98, 98);
//	    addChild(_nfcFeedback.getSprite());
//	    float x = winSize.width - 115 * 2 - 10 ;
//	    float y = 98 * 2 + 10;
//	    
//	    addChild(_actions.getNode());
//	    
//	    //Schedule update and enable touch
//	    this.schedule("update");
//	    this.schedule("serverUpdate", 0.1f);
//	    this.setIsTouchEnabled(true);
//	    this.setIsAccelerometerEnabled(true);
//	    
//	    currentArbject = null;
	    
//	    Context context = CCDirector.sharedDirector().getActivity();
//	    SoundEngine.sharedEngine().preloadEffect(context, R.raw.pew_pew_lei);
//	    SoundEngine.sharedEngine().playSound(context, R.raw.background_music_aac, true);
	}
	
	/** Main game loop */
	public void update(float dt) {
		for(CocosComponent component : cocosComponents){
			component.update(dt, arManager);
		}
		arManager.update();
	}
	
	public void addComponent(CocosComponent newComponent){
		addChild(newComponent.getNode());
		cocosComponents.add(newComponent);
	}
	
	/**
	 * @Override Implementation of touches began event
	 */
	public boolean ccTouchesBegan(MotionEvent event) {
		//
		CGPoint touchPoint = CCDirector.sharedDirector().convertToGL(
				CGPoint.ccp(event.getX(), event.getY()));
		CGRect fingerRect = CGRect.make(touchPoint.x - 22, touchPoint.y - 22,
				44, 44);
		int touchID = event.getPointerId(event.getActionIndex());
		//
		for(CocosComponent component : cocosComponents){
			if(component.isIntersecting(fingerRect) && component.isVisible()){
				component.touchBegan(touchID, touchPoint);
			}
		}
		return true;
	}

	/**
	 * @Override Implementation of touches moved event
	 */
	public boolean ccTouchesMoved(MotionEvent event) {
		// Iterate through all touches
		for (int i = 0; i < event.getPointerCount(); i++) {
			CGPoint touchPoint = CCDirector.sharedDirector().convertToGL(
					CGPoint.ccp(event.getX(i), event.getY(i)));
			CGRect fingerRect = CGRect.make(touchPoint.x - 22,
					touchPoint.y - 22, 44, 44);
			int touchID = event.getPointerId(i);
			
			for(CocosComponent component : cocosComponents){
				if(component.isIntersecting(fingerRect) && component.isVisible()){
					component.updateTouch(touchID, touchPoint);
				}
			}
		}

		return true;
	}

	/**
	 * @Override Implementation of touches ended event
	 */
	public boolean ccTouchesEnded(MotionEvent event) {
		int touchID = event.getPointerId(event.getActionIndex());
		
		for(CocosComponent component : cocosComponents){
			if(component.hasTouchID(touchID)){
				component.touchEnded(touchID, arManager);
			}
		}
		return true;
	}
	
	@Override
	public void ccAccelerometerChanged(float ax, float ay, float az){
		arManager.accelerometerChanged(ax, ay, az);
	}

	public void setARManager(ARManager arManager) {
		this.arManager = arManager;
	}

	/** Implementation of objective-c like allocation for this object */
	public static CCScene scene() {
		CCScene scene = CCScene.node();
		CCLayer layer = new GameLayer(new ccColor4B(0, 0, 255, 0));

		scene.addChild(layer);

		return scene;
	}

//	/** Main game loop */
////	public void update(float dt) {
////		// Update GUI
////		_nfcFeedback.update(dt);
////		_actions.update(dt);
////	    count += dt;
////	}
//
//	/**Server loop
//	 * @throws ExecutionException 
//	 * @throws InterruptedException */
////	public void serverUpdate(float dt){
////		arManager.serverUpdate();
//////		arManager.serverPlayerUpdate();
////	}
//
//	/**
//	 * Sets a shared variable on the server to a specified value. This variable
//	 * will then be accessed by all clients for synchronization.
//	 * 
//	 * @param key
//	 *            The variable to be set.
//	 * @param value
//	 *            The value to set the variable to.
//	 */
//	public void setSharedData(String key, String value) {
//		new Client().execute(key + ":" + value);
//	}
//
//	/**
//	 * Get the value for a shared variable on the server.
//	 * 
//	 * @param key
//	 *            The variable that you want the value for.
//	 * @return The value for the parameter {@code key}, represented as a
//	 *         {@link java.lang.String}.
//	 * @throws InterruptedException
//	 * @throws ExecutionException
//	 */
//	public String getSharedData(String key) throws InterruptedException,
//			ExecutionException {
//		return new Client().execute(key).get();
//	}
//
//	/**
//	 * @Override Implementation of touches began event
//	 */
//	public boolean ccTouchesBegan(MotionEvent event) {
//		//
//		CGPoint touchPoint = CCDirector.sharedDirector().convertToGL(
//				CGPoint.ccp(event.getX(), event.getY()));
//		CGRect fingerRect = CGRect.make(touchPoint.x - 22, touchPoint.y - 22,
//				44, 44);
//		int touchID = event.getPointerId(event.getActionIndex());
//		//
//		if (_nfcFeedback.isIntersecting(fingerRect)) {
//			_nfcFeedback.setTouchID(touchID);
//		} else if (_actions.isIntersecting(fingerRect)) {
//			_actions.startTouch(touchID, touchPoint);
//		}
//		
//		return true;
//	}
//
//	/**
//	 * Convert the 4D input into 3D space (or something like that, otherwise the
//	 * gluUnproject values are incorrect)
//	 * 
//	 * @param v
//	 *            4D input
//	 * @return 3D output
//	 * @author http://stackoverflow.com/users/1029225/mh
//	 */
//	public static float[] fixW(float[] v) {
//		float w = v[3];
//		for (int i = 0; i < 4; i++)
//			v[i] = v[i] / w;
//		return v;
//	}
//
//	/**
//	 * check if a given point in space collides with a given object center with
//	 * a given radius based on ios code from:
//	 * http://blog.nova-box.com/2010/05/iphone
//	 * -ray-picking-glunproject-sample.html
//	 * 
//	 * @param point
//	 *            point to check for collision with object x,y,z
//	 * @param center
//	 *            center of the object x,y,z
//	 * @param radius
//	 * @return true on collision, false on no collision
//	 */
//	public static boolean pointSphereCollision(float[] point, float[] center,
//			float radius) {
//
//		return ((point[0] - center[0]) * (point[0] - center[0])
//				+ (point[1] - center[1]) * (point[1] - center[1])
//				+ (point[2] - center[2]) * (point[2] - center[2]) < (radius * radius));
//	}
//
//	/**
//	 * @Override Implementation of touches moved event
//	 */
//	public boolean ccTouchesMoved(MotionEvent event) {
//		boolean touchingDPad = false;
//		// Iterate through all touches
//		for (int i = 0; i < event.getPointerCount(); i++) {
//			CGPoint touchPoint = CCDirector.sharedDirector().convertToGL(
//					CGPoint.ccp(event.getX(i), event.getY(i)));
//			CGRect fingerRect = CGRect.make(touchPoint.x - 22,
//					touchPoint.y - 22, 44, 44);
//			int touchID = event.getPointerId(i);
//			// A touch is intersecting with the d-pad, so update d-pads touch ID
//			if (_nfcFeedback.isIntersecting(fingerRect)) {
//				if (_nfcFeedback.hasTouchID(touchID)) {
//				} else {
//					_nfcFeedback.setTouchID(touchID);
//				}
//				touchingDPad = true;
//			}
//			// A touch is intersecting with the actions, so update actions touch
//			// ID
//			else if (_actions.isIntersecting(fingerRect)) {
//				if (_actions.hasTouchID(touchID)) {
//					_actions.updateTouch(touchPoint);
//					performHoldAction();
//				} else {
//					_actions.startTouch(touchID, touchPoint);
//				}
//			}
//		}
//		if (!touchingDPad) {
//			_nfcFeedback.setTouchID(-1);
//		}
//		return true;
//	}
//
//	/**
//	 * @Override Implementation of touches ended event
//	 */
//	public boolean ccTouchesEnded(MotionEvent event) {
//		int touchID = event.getPointerId(event.getActionIndex());
//		// Touch which ended had ID of the d-pad
//		if (_nfcFeedback.hasTouchID(touchID)) {
//			_nfcFeedback.setTouchID(-1);
//		}
//		// Touch which ended had the ID of the actions
//		else if (_actions.hasTouchID(touchID)) {
//			if (_actions.wasSwiped()) {
//				_actions.swapActions();
//			}
//			//
//			else {
//				performTapAction();
//			}
//			_actions.resetTouch();
//		}
//		return true;
//	}
//
//	/** Actions to be performed when the action slots were tapped */
//	private void performTapAction() {
//		if (currentArbject != null) {
//			if(_actions.contentIs("slope1")){
//				arManager.addModel(currentArbject.getID(), "ski_slope_2");
//			} else if(_actions.contentIs("slope2")){
//				arManager.addModel(currentArbject.getID(), "ski_slope_3");
//			} else if(_actions.contentIs("slope3")){
//				arManager.addModel(currentArbject.getID(), "ski_slope_1");
//			} else if(_actions.contentIs("turnL")){
//				arManager.addModel(currentArbject.getID(), "ski_slope_left_turn");
//			} else if(_actions.contentIs("turnR")){
//				arManager.addModel(currentArbject.getID(), "ski_slope_right_turn");
//			} else if(_actions.contentIs("skier")){
//				arManager.addSkier(currentArbject.getID());
////				arManager.addModel(currentArbject.getID(), "skier");
//			} else if(_actions.contentIs("clear")){
//				arManager.clearArbject((currentArbject.getID()));
//			}
//
////			_nfcFeedback.setImage("none");
////			_actions.setVisible(false);
//
////			currentArbject = null;
//		}
//	}
//
//	/** Actions to be performed when the action slots are tapped and held */
//	private void performHoldAction() {
//	}
//	
//	@Override
//	public void ccAccelerometerChanged(float ax, float ay, float az){
//		if(currentArbject != null){
////			arManager.setSkiAngle(currentArbject.getID(), ax, ay, az);
//			currentArbject.changeSkierAngle(-1f * ay);
//		}
//	}
//
//	public void receiveNFC(String id) {
//		// Log.d("TAG", id);
//		currentArbject = arManager.getArbject(id);
//		_nfcFeedback.setImage(currentArbject.getName());
//		_actions.setVisible(true);
//	}
//
//	public void setARManager(ARManager arManager) {
//		this.arManager = arManager;
//	}
//
//	/** Implementation of objective-c like allocation for this object */
//	public static CCScene scene() {
//		CCScene scene = CCScene.node();
//		CCLayer layer = new GameLayer(new ccColor4B(0, 0, 255, 0));
//
//		scene.addChild(layer);
//
//		return scene;
//	}
}
